#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "errno.h"
#include "malloc.h"
#include <Windows.h>
#include <time.h>

#define BLOCKSIZE 1024

const char *monabb[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};

char *runCmd(char *cmd)
{
	FILE *fp = NULL;
	char *result = NULL;
	unsigned long int blocksize = 1;

	fp = _popen(cmd,"r");
	if(fp == NULL)
	{
		perror("popen failed");
		exit(1);
	}
	else
	{
		while((feof(fp) == 0))
		{
			result = realloc(result,BLOCKSIZE * blocksize * sizeof(char));
			if(result == NULL)
			{
				perror("popen failed");
				break;
			}
			memset((char *)(result + (BLOCKSIZE * (blocksize - 1))),'\0',BLOCKSIZE);
			fread((char *)(result + (BLOCKSIZE * (blocksize - 1))),sizeof(char),BLOCKSIZE,fp);
			blocksize ++;
		}
	}
	_pclose(fp);

	return result;
}

void getGitVersion(char *path,char *version,char *time)
{
	char *result = NULL,*result1 = NULL,*str = NULL;
	char tmpbuf[128] = {0};
	
	if(version == NULL || time == NULL)	return;
	
	//if(((result = runCmd("git diff")) != NULL) && (strlen(result)))
	//{
	//	printf("Please commit first !\r\n");
	//	getchar();
		//printf("%s\r\n",result);
	//	free(result);
	//	exit(0);
	//}
	
	result = runCmd("git show");
	sscanf(strstr(result,"commit"),"commit %s",version);	
	//printf("current_ver_commit = %s\r\n",version);	
	sscanf(strstr(result,"Date:"),"%*s   %[^+]",time);	
	//printf("commit time = %s\r\n",time);
	free(result);
	
	result = runCmd("git tag");
	str = strtok(result,"\n");
	while(str != NULL)
	{
		//printf("tag %s\r\n",str);
		memset(tmpbuf,'\0',128);
		sprintf(tmpbuf,"git show %s",str);
		result1 = runCmd(tmpbuf);
		//printf("result1 \r\n%s\r\n",result1);
		memset(tmpbuf,'\0',128);
		sscanf(strstr(result1,"commit"),"commit %s",tmpbuf);			
		//printf("ver_commit = %s",ver_commit);	
		if(!strcmp(version,tmpbuf))
		{
			memset(version,'\0',64);
			memset(time,'\0',64);
			strcpy(version,str);
			sscanf(strstr(result1,"Date:"),"%*s   %[^+]",time);
			free(result1);
			break;
		}
		free(result1);
		str = strtok(NULL,"\n");
	}
	time[strlen(time) - 1] = 0;
	version[16] = 0;
	if(((result = runCmd("git diff")) != NULL) && (strlen(result)))
		strcat(version,"_DirtyCode");
	free(result);
}

void asctime2mytime(char *asctime,char *mytime)
{
	char year[5] = {0};
	char mon[4] = {0};
	char day[3] = {0};
	char h[3] = {0};
	char m[3] = {0};
	char s[3] = {0};
	char tt[16] = {0};
	char i = 0;
	char *str = NULL;
	strcpy(mytime,asctime);
	
	str = strtok(mytime," ");
	while(str != NULL)
	{	
		if(i == 1)
			strcpy(mon,str);
		if(i == 2)
			strcpy(day,str);
		if(i == 3)
			strcpy(tt,str);
		if(i == 4)
			strcpy(year,str);
		i ++;
		str = strtok(NULL," ");
		//printf("time str %d:%s\r\n",i,str);
	}

	i = 0;
	str = strtok(tt,":");
	while(str != NULL)
	{
		//printf("time str %d:%s\r\n",i,str);
		if(i == 0)
			strcpy(h,str);
		if(i == 1)
			strcpy(m,str);
		if(i == 2)
			strcpy(s,str);
		i ++;
		str = strtok(NULL,":");	
	}

	i = 0;
	while(i < 12)
	{
		if(strcmp(mon,monabb[i]) == 0)
			break;
		i ++;
	}
	memset(mytime,0,strlen(mytime));
	sprintf(mytime,"%04s%02d%02s-%02s%02s%02s",year,i+1,day,h,m,s);
	//printf("mytime=%s\r\n",mytime);
}

void getCompileSysInfo(char *sys_info)
{
	char *result = NULL;
	char caption1[64] = {0};
	char caption2[64] = {0};
	char version[128] = {0};
	char osarchitecture[128] = {0};
	char csname[128] = {0};

	result = runCmd("wmic os get caption");
	sscanf(result,"%*s %*s %s",caption1);
	sscanf(result,"%*s %*s %*s %s",caption2);
	//printf("%s %s\r\n",caption1,caption2);
	free(result);

	result = runCmd("wmic os get version");
	sscanf(result,"%*s %s",version);
	//printf("%s\r\n",version);
	free(result);

	result = runCmd("wmic os get osarchitecture");
	sscanf(result,"%*s %s",osarchitecture);
	//printf("%s\r\n",osarchitecture);
	free(result);

	result = runCmd("wmic os get csname");
	sscanf(result,"%*s %s",csname);
	//printf("%s\r\n",csname);
	free(result);

	memset(sys_info,0,strlen(sys_info));
	sprintf(sys_info,"%s%s(%s,%s)@%s",caption1,caption2,version,osarchitecture,csname);
	//printf("%s\r\n",sys_info);
}

void getCompilerInfo(char *ide,char *compiler_info)
{
	FILE *fp = NULL;
	char line[1024] = {0};
 
	fp = fopen(ide, "r");
	while (!feof(fp))
	{
		fgets(line,1024,fp);
		//printf("%s",line);
		if(strstr(line,"OGLastSavedByProductVersion"))
		{
			fgets(line,1024,fp);
			//printf("%s",line);
			strcpy(compiler_info,"IAR(");
			break;
		}
		else if(strstr(line,"</pCCUsed>"))
		{
			//printf("%s",line);
			strcpy(compiler_info,"MDK(");
			break;
		}
	}
	fclose(fp);

	sscanf(strstr(line,">"),">%[^<]",line);
	//printf("%s",line);
	strcat(compiler_info,line);
	strcat(compiler_info,")");
}

void getBuildTime(char *build_time)
{
	time_t timep;
    struct tm *p;

    time(&timep);
    //p = gmtime(&timep);
	p = localtime(&timep);

	memset(build_time,0,strlen(build_time));

	//printf("%04d%02d%02d-%02d%02d%02d",p->tm_year+1900,p->tm_mon+1,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec);
	sprintf(build_time,"%04d%02d%02d-%02d%02d%02d",p->tm_year+1900,p->tm_mon+1,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec);
}

int main(int argc,char *argv[])
{
	FILE *fp = NULL;
	char version[256] = {0};
	char time[128] = {0};
	char mytime[128] = {0};
	char sys_info[128] = {0};
	char compiler_info[128] = "none";
	char build_time[128] = "none";
	
	if((argc > 1) && (strcmp(argv[1],"clean") == 0))
	{
		runCmd("git checkout ./prg_version.h");
		return 0;
	}

	getBuildTime(build_time);
	getGitVersion(NULL,version,time);
	asctime2mytime(time,mytime);
	getCompileSysInfo(sys_info);
	if(argc > 1)
		getCompilerInfo(argv[1],compiler_info);

	if((fp = fopen("./prg_version.h","w+")) != NULL)
	{
		fprintf(fp,"#ifndef _PRG_VERSION_H_\n");
		fprintf(fp,"#define _PRG_VERSION_H_\n");
		fprintf(fp,"#define PRG_VERSION \"");
		if(argc > 2 && (strcmp(argv[1],"add_info") == 0))
			fprintf(fp,"%s_",argv[2]);
		fprintf(fp,"%s_%s\"\n",version,mytime);
		fprintf(fp,"#define BUILD_TIME \"%s\"\n",build_time);
		fprintf(fp,"#define COMPILE_SYSINFO \"%s\"\n",sys_info);
		fprintf(fp,"#define COMPILER_INFO \"%s\"\n",compiler_info);
		fprintf(fp,"#endif\n");
	}
	else
	{
		perror("fopen failed");
	}
	fclose(fp);
	
	/*
	if((fp = fopen("./version.mk","w+")) != NULL)
	{
		if(argc > 1)
			fprintf(fp,"VERSION=%s_%s_%s\n",argv[1],version,mytime);
		else
			fprintf(fp,"VERSION=%s_%s\n",version,mytime);
	}
	else
	{
		perror("fopen failed");
	}
	fclose(fp);
	*/
	
	/* 	
	char *result = NULL;
 	result = runCmd("git log");
	printf("%s",result);
	free(result);  
	*/

	return 0;
}





